package cn.datawin.bms.modules.deploy.service.impl;

import cn.datawin.bms.deploy.entity.DeplBranchInfoEntity;
import cn.datawin.bms.deploy.entity.DeplDockerInfoEntity;
import cn.datawin.bms.deploy.entity.DeplModuleInfoEntity;
import cn.datawin.bms.deploy.entity.DeplServerModuleInfoEntity;
import cn.datawin.bms.modules.deploy.mapper.DeplDockerInfoMapper;
import cn.datawin.bms.modules.deploy.service.DeplBranchInfoService;
import cn.datawin.bms.modules.deploy.service.DeplDockerInfoService;
import cn.datawin.bms.modules.deploy.service.DeplModuleInfoService;
import cn.datawin.bms.modules.deploy.service.DeplServerModuleInfoService;
import cn.datawin.common.core.util.R;
import cn.datawin.constant.DOCKER;
import cn.datawin.dockerclient.dto.ActiveDto;
import cn.datawin.dockerclient.feign.RemoteDockerService;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * docker容器表
 *
 * @author shengdongcloud
 * @date 2025-03-13 09:53:03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeplDockerInfoServiceImpl extends ServiceImpl<DeplDockerInfoMapper, DeplDockerInfoEntity> implements DeplDockerInfoService {

	private final RemoteDockerService remoteDockerService;
	private final DeplServerModuleInfoService deplServerModuleInfoService;
	private final DeplModuleInfoService deplModuleInfoService;
	private final DeplBranchInfoService deplBranchInfoService;

	/**
	 * 激活docker容器
	 * @param entity
	 * @return
	 */
	@Override
	public boolean activeContainer(DeplDockerInfoEntity entity) {
		//获取选中服务器信息
		DeplServerModuleInfoEntity serverModuleInfo = deplServerModuleInfoService.getById(entity.getServerModuleInfoId());
		//远程调用docker-client服务激活容器
		ActiveDto activeDto = new ActiveDto();
		activeDto.setModuleId(entity.getModuleId());
		activeDto.setBranchId(entity.getBranchId());
		activeDto.setContainerName(entity.getContainerName());
		activeDto.setConfigJson(entity.getConfigJson());
		activeDto.setServerIp(serverModuleInfo.getServerIp());
		activeDto.setServerPort(serverModuleInfo.getServerPort());

		R result = remoteDockerService.active(activeDto);
		log.info("激活容器返回结果：{}", JSON.toJSONString(result));
		//激活成功
		return result.getCode() == 0;

	}

	@Override
	public boolean stopContainer(Integer id) {
		R result = remoteDockerService.stop(id);
		log.info("停止容器返回结果：{}", JSON.toJSONString(result));
		return result.getCode() == 0;
	}

	@Override
	public boolean restartContainer(Integer id) {
		R result = remoteDockerService.restart(id);
		log.info("启动容器返回结果：{}", JSON.toJSONString(result));
		return result.getCode() == 0;
	}

	@Override
	public boolean removeContainer(Integer id) {
		R result = remoteDockerService.remove(id);
		log.info("废弃容器返回结果：{}", JSON.toJSONString(result));
		return result.getCode() == 0;
	}

	@Override
	public boolean cleanContainer(Integer id) {
		DeplDockerInfoEntity entity = new DeplDockerInfoEntity();
		entity.setId(id);
		entity.setStatus(DOCKER.STATUS.CLEARED);
		return SqlHelper.retBool(this.getBaseMapper().updateById(entity));
	}

	@Override
	public boolean editContainer(DeplDockerInfoEntity dockerInfo) {
		DeplServerModuleInfoEntity serverModuleInfo = deplServerModuleInfoService.getById(dockerInfo.getServerModuleInfoId());
		dockerInfo.setServerIp(serverModuleInfo.getServerIp());
		dockerInfo.setOutServerPort(serverModuleInfo.getServerPort());
		dockerInfo.setInnerServerPort(serverModuleInfo.getServerPort());
		this.getBaseMapper().updateById(dockerInfo);
		return true;
	}

	@Override
	public boolean rebornContainer(Integer id) {
		DeplDockerInfoEntity entity = this.getById(id);

		/**
		 * 	R active(@RequestParam int module_id, @RequestParam int branch_id, @RequestParam String container_name,
		 *                          @RequestParam String config_json, @RequestParam String server_ip, @RequestParam String server_port);
		 */
		R result = remoteDockerService.reborn(id);
		log.info("激活容器返回结果：{}", JSON.toJSONString(result));
		if (result.getCode() == 0) {//激活成功
			//端口占用更新
			LambdaUpdateWrapper<DeplServerModuleInfoEntity> query = new LambdaUpdateWrapper<>();
			query.eq(DeplServerModuleInfoEntity::getServerIp, entity.getServerIp())
					.eq(DeplServerModuleInfoEntity::getServerPort, entity.getOutServerPort())
					.set(DeplServerModuleInfoEntity::getStatus, 1);
			deplServerModuleInfoService.update(query);
			return true;
		}

		return false;
	}

	@Override
	public boolean upgradeContainer(DeplDockerInfoEntity dockerInfo) {
		// 升级docker容器的分支
		DeplDockerInfoEntity t = new DeplDockerInfoEntity();
		t.setId(dockerInfo.getId());
		t.setBranchId(dockerInfo.getBranchId());
		this.getBaseMapper().updateById(t);
		// 停止容器
		R stopResult = remoteDockerService.stop(dockerInfo.getId());
		log.info("停止容器返回结果：{}", stopResult);
		// 删除容器
		R removeResult = remoteDockerService.remove(dockerInfo.getId());
		log.info("删除容器返回结果：{}", removeResult);
		// 复活容器
		DeplDockerInfoEntity entity = this.getById(dockerInfo.getId());
		R rebornResult = remoteDockerService.reborn(dockerInfo.getId());
		log.info("复活容器返回结果：{}", rebornResult);
		if (rebornResult.getCode() == 0) {//复活成功
			LambdaUpdateWrapper<DeplServerModuleInfoEntity> query = new LambdaUpdateWrapper<>();
			query.eq(DeplServerModuleInfoEntity::getServerIp, entity.getServerIp())
					.eq(DeplServerModuleInfoEntity::getServerPort, entity.getOutServerPort())
					.set(DeplServerModuleInfoEntity::getStatus, 1);
			deplServerModuleInfoService.update(query);
		}
		return true;
	}

	@Override
	public void wrapData(List<DeplDockerInfoEntity> records) {
		if (CollUtil.isEmpty(records)) {
			return;
		}
		List<Integer> moduleIds = new ArrayList<>();
		List<Integer> branchIds = new ArrayList<>();
		for (DeplDockerInfoEntity record : records) {
			Integer moduleId = record.getModuleId();
			if(moduleId != null && !moduleIds.contains(moduleId)){
				moduleIds.add(moduleId);
			}
			Integer branchId = record.getBranchId();
			if (branchId != null && !branchIds.contains(branchId)) {
				branchIds.add(branchId);
			}
		}

		//查询模块信息
		List<DeplModuleInfoEntity> moduleInfoEntities = this.deplModuleInfoService.listByIds(moduleIds);
		Map<Integer, DeplModuleInfoEntity> collect = moduleInfoEntities.stream().collect(Collectors.toMap(DeplModuleInfoEntity::getId, a -> a));
		//查询分支信息
		List<DeplBranchInfoEntity> branchInfoEntities = this.deplBranchInfoService.listByIds(branchIds);
		Map<Integer, DeplBranchInfoEntity> collect1 = branchInfoEntities.stream().collect(Collectors.toMap(DeplBranchInfoEntity::getId, a -> a));
		for (DeplDockerInfoEntity record : records) {
			DeplModuleInfoEntity deplModuleInfoEntity = collect.get(record.getModuleId());
			if (deplModuleInfoEntity != null) {
				record.setModuleName(deplModuleInfoEntity.getName());
			}
			DeplBranchInfoEntity deplBranchInfoEntity = collect1.get(record.getBranchId());
			if (deplBranchInfoEntity != null) {
				record.setBranchName(deplBranchInfoEntity.getName());
			}
		}
	}
}
